package com.welike.shibo.controller.api;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.welike.shibo.controller.BaseController;
import com.welike.shibo.eneity.*;
import com.welike.shibo.enums.ResultEnum;
import com.welike.shibo.service.FansService;
import com.welike.shibo.service.LogService;
import com.welike.shibo.service.MsgService;
import com.welike.shibo.service.UserService;
import com.welike.shibo.utils.PasswordEncrypt;
import com.welike.shibo.utils.ResultUtils;
import com.welike.shibo.vo.UserInfoVO;
import com.welike.shibo.vo.page.FansPageVo;
import com.welike.shibo.vo.page.SearchUserPageVo;
import com.welike.shibo.vo.page.StarPageVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @author fangyu
 * @version v1.0.0
 * @since 2019-08-19 18:44
 */

@Slf4j
@Api(value = "用户数据接口")
@RestController
@RequestMapping("/api/user")
public class ApiUserController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private FansService fansService;

    @Autowired
    private MsgService msgService;

    @Autowired
    private LogService logService;

    /**
     * 查看个人信息
     *
     * @return JsonResult
     */
    @ApiOperation(value = "查看个人信息")
    @GetMapping("/person_info")
    public JsonResult modifyPwd() {
        map.clear();
        LoginUser loginUser = (LoginUser) getUser4Session();
        if (loginUser == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
        }
        String uid = loginUser.getUid();
        UserInfoVO userInfoVO = userService.queryUserInfo(uid);
        map.put("userInfo", userInfoVO);
        map.put("path", "/api/user/person_info");
        return ResultUtils.success(map);
    }


    /**
     * 修改密码
     *
     * @return JsonResult
     */
    @ApiOperation(value = "修改密码")
    @PostMapping("/modify_pwd")
    public JsonResult modifyPwd(
//            @RequestParam(value = "phone") String phone,
            @RequestParam(value = "oldPwd") String oldPwd,
            @RequestParam(value = "newPwd") String newPwd
    ) {
        map.clear();
        try {
            LoginUser loginUser = (LoginUser) getUser4Session();
            if (loginUser == null) {
                return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
            }
            User user = userService.getById(loginUser.getId());
            String password = PasswordEncrypt.encodeByMd5(oldPwd);
            if (!user.getPassword().equals(password)) {
                return ResultUtils.error(ResultEnum.PASSWORD_ERROR.getCode(), "密码不正确");
            } else {
                user.setPassword(PasswordEncrypt.encodeByMd5(newPwd));
                userService.updateById(user);
            }
            logService.save(new Log(user.getUid(), "已修改密码:", new Date()));
            log.info("账号:" + loginUser.getUid() + "已成功修改密码！");
            //修改密码后，使原来的session失效。
            setSession(null);
        } catch (Exception e) {
            log.error("modifyPwd error Exception:{}", e.getMessage());
            return ResultUtils.error(500, e.getMessage());
        }
        map.put("path", "/api/user/modify_pwd");
        return ResultUtils.success("密码修改成功!", map);
    }

    /**
     * 修改个人资料
     *
     * @return JsonResult
     */
    @ApiOperation(value = "修改个人资料")
    @PostMapping("/modify_info")
    public JsonResult modifyPersonInfo(
            @ApiParam(name = "nickname", value = "昵称", required = true)
            @RequestParam(value = "nickname") String nickname,
            @ApiParam(name = "gender", value = "性别,1-男,2-女", required = true)
            @RequestParam(value = "gender") Integer gender,
            @ApiParam(name = "signature", value = "个性签名", required = true)
            @RequestParam(value = "signature") String signature,
            @ApiParam(name = "birthday", value = "生日", required = true)
            @RequestParam(value = "birthday") String birthday,
            @ApiParam(name = "address", value = "城市", required = true)
            @RequestParam(value = "address") String address
    ) {
        map.clear();
        LoginUser loginUser = (LoginUser) getUser4Session();
        if (loginUser == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
        }
        User user = new User();
        log.info("loginUser ==> {}", loginUser);
//        user.setUid(loginUser.getUid());
        user.setId(loginUser.getId());
        user.setNickname(nickname);
        user.setGender(gender);
        user.setSignature(signature);
        user.setBirthday(birthday);
        user.setAddress(address);
        boolean result = userService.updateById(user);
        if (result) {
//            User queryUser = userService.queryUserByUid(loginUser.getUid());
            UserInfoVO userInfoVO = userService.queryUserInfo(loginUser.getUid());
            map.put("userInfo", userInfoVO);
            map.put("path", "/api/user/modify_info");
            return ResultUtils.success("修改成功！", map);
        } else {
            return ResultUtils.error(ResultEnum.MODIFY_FAIL.getCode(), ResultEnum.MODIFY_FAIL.getMsg());
        }
    }

    /**
     * 查询其他用户信息(不登录也可以调用)
     *
     * @return JsonResult
     */
    @ApiOperation(value = "查询其他用户信息", notes = "通过uid查询其他用户的信息")
    @GetMapping("/info")
    public JsonResult getUserInfo(
            @RequestParam(value = "uid") String uid
    ) {
        map.clear();
        User user = userService.queryUserByUid(uid);
        UserInfoVO userInfoVO = userService.queryUserInfo(uid);
        LoginUser loginUser = (LoginUser) getUser4Session();
        // 查询关注状态
        if (loginUser != null) {
            String result = fansService.queryIdByUserIdAndFanId(uid, loginUser.getUid());
            if (result != null) {
                userInfoVO.setFollowState(true);
            } else {
                userInfoVO.setFollowState(false);
            }
        }
        map.put("userInfo", userInfoVO);
        map.put("path", "/api/user/info");
        return ResultUtils.success(map);
    }

    /**
     * 关注/取消关注
     *
     * @return JsonResult
     */
    @ApiOperation(value = "关注/取消关注")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "uid", value = "指定关注用户的id", required = true)})
    @PostMapping("/follow")
    public JsonResult followUser(
            @RequestParam(value = "uid") String uid
    ) {
        map.clear();
        map.put("path", "/api/user/follow");
        LoginUser user = (LoginUser) getUser4Session();
        if (user == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
        }
        // 判断是否有此用户
        if (!userService.queryUid(uid)) {
            return ResultUtils.error(ResultEnum.USER_NOT_EXIST.getCode(), "用户不存在", map);
        }
        // 排除关注自己
        if (uid.equals(user.getUid())){
            return ResultUtils.error(ResultEnum.PARAM_ERROR.getCode(), "不能关注用户自己!", map);
        }
        Fans fans = new Fans();
        // 先查有木有关注过, 关注了则直接, 自己作为fanId, 传入对象为uid
        String result = fansService.queryIdByUserIdAndFanId(uid, user.getUid());
        if (result != null) {
            fansService.removeById(result);
            // 更新关注数少1
            map.put("followStatus", false);
            return ResultUtils.success("已取消关注", map);
        }
        fans.setUserId(uid);
        fans.setFanId(user.getUid());
        fans.setCreateTime(new Date());
        log.info("fans ==> {}", fans);
        fansService.save(fans);
        String title = user.getNickname()+" 关注了你";
        // 关注新增推送
        boolean push_result = msgService.pushMsg(2, uid, title, null, null);
        if (push_result) {
            Msg msg = new Msg();
            msg.setUserId(uid);
            msg.setCreateTime(new Date());
            msg.setMsgTitle(title);
            msg.setMsgContent("");
            msg.setMsgType(2);
            msgService.save(msg);
        }
        map.put("followStatus", true);
        return ResultUtils.success("已关注", map);
    }

    /**
     * 上传头像
     *
     * @return JsonResult
     */
    @ApiOperation(value = "上传头像")
    @PostMapping("/upload_avatar")
    public JsonResult upload_avatar(
            @ApiParam(name = "uploadFile", value = "上传头像", required = true)
            @RequestParam(value = "uploadFile") MultipartFile avatar
    ) throws IOException {
        map.clear();
        map.put("path", "/api/user/upload_avatar");
        LoginUser user = (LoginUser) getUser4Session();
        log.info("upload_avatar: loginUser ==> {}", user);
        if (user == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
        }
        String avatarUrl = userService.uploadAvatar(avatar);
        User user1 = new User();
        user1.setAvatar(avatarUrl);
        user1.setId(user.getId());
        boolean result = userService.updateById(user1);
        if (result) {
            map.put("avatarUrl", avatarUrl);
            return ResultUtils.success("成功修改头像！", map);
        } else {
            return ResultUtils.error(ResultEnum.MODIFY_FAIL.getCode(), ResultEnum.MODIFY_FAIL.getMsg());
        }
    }

    /**
     * 查询自己关注的人
     *
     * @param page     页码
     * @param pageSize 页大小
     * @return JsonResult
     */
    @ApiOperation(value = "查询自己关注的人")
    @GetMapping("/list/follow")
    public JsonResult follow_list(
            @RequestParam(value = "page", required = false, defaultValue = "1") int page,
            @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize
    ) {
        map.clear();
        LoginUser user = (LoginUser) getUser4Session();
        log.info("follow_list: loginUser ==> {}", user);
        if (user == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
        }
        List<StarPageVo> starPageVoList = fansService.queryFollowStarPage(page, pageSize, user.getUid());
        map.put("pageList", starPageVoList);
        map.put("page", page);
        map.put("pageSize", pageSize);
        map.put("path", "/api/user/list/follow");
        return ResultUtils.success(map);

    }

    /**
     * 查询自己的粉丝
     *
     * @param page     页码
     * @param pageSize 页大小
     * @return JsonResult
     */
    @ApiOperation(value = "查询自己的粉丝")
    @GetMapping("/list/fans")
    public JsonResult fans_list(
            @RequestParam(value = "page", required = false, defaultValue = "1") int page,
            @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize
    ) {
        map.clear();
        map.put("path", "/api/user/list/fans");
        LoginUser user = (LoginUser) getUser4Session();
        log.info("follow_list: loginUser ==> {}", user);
        if (user == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg(), map);
        }
        // 一、以自己为出发点(user_id = uid)，查询所有自己的fans_id
        List<FansPageVo> fansPageVoList = fansService.queryFansPage(page, pageSize, user.getUid());
        map.put("pageList", fansPageVoList);
        map.put("page", page);
        map.put("pageSize", pageSize);
        return ResultUtils.success(map);
    }


    @ApiOperation(value = "搜索用户", notes = "用户根据关键词搜索用户")
    @GetMapping("/search")
    public JsonResult search(
            @RequestParam(value = "key", required = false) String key,
            @RequestParam(value = "page", required = false, defaultValue = "1") int page,
            @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize
    ) {
        map.clear();
        map.put("path", "/api/user/search");
        IPage<SearchUserPageVo> result = userService.searchUser(page, pageSize, key);
        map.put("pageList", result.getRecords());
        map.put("page", page);
        map.put("pageSize", pageSize);
        return ResultUtils.success(map);
    }

}
